package ltd.dujiabao.channel;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

/**
 * @author : DuJiabao
 * @Project : io_test
 * @Time : 2021/5/30 20:00
 * @Desc :
 */
public class ChannelTest {
  @Test
  public void testInputChannel() throws IOException {
    FileInputStream fis = new FileInputStream("src/main/resources/data.txt");
    FileChannel channel = fis.getChannel();
    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);  // 定义一个缓冲区
    channel.read(byteBuffer);  // 通过通道读数据
    // 反转为读
    byteBuffer.flip();
    System.out.println(new String(byteBuffer.array(), 0, byteBuffer.remaining()));  // 将读出来的数据变成字符串
  }

  @Test
  public void testOutputChannel() {
    try (FileOutputStream fos = new FileOutputStream("src/main/resources/data0.txt")) {
      FileChannel channel = fos.getChannel();
      ByteBuffer byteBuffer = ByteBuffer.allocate(20);
      byteBuffer.put("你好世界".getBytes());
      byteBuffer.flip();  // 反转模式
      channel.write(byteBuffer);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Test
  public void testCopyLargeFile() throws IOException {
    FileChannel outChannel = new FileOutputStream("src/main/resources/壁纸2.jpg").getChannel();  // 获取输出通道
    FileChannel inputChannel = new FileInputStream("src/main/resources/壁纸.jpg").getChannel();  // 获取输入通道

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);  // 创建一个新的缓存区。这里图有趣用了一个直接内存
    while (inputChannel.read(byteBuffer) != -1) {  // 读数据
      byteBuffer.flip();  // 反转为读操作
      outChannel.write(byteBuffer);  // 将数据输出到文件中
      byteBuffer.clear(); // 清空缓存
    }
    // 记得关闭
    outChannel.close();
    inputChannel.close();
  }

  @Test
  public void testScatterAndGather() throws IOException {
    RandomAccessFile inputFile = new RandomAccessFile("src/main/resources/data.txt", "rw");  // 获取可以随机存取的文件
    FileChannel inChannel = inputFile.getChannel();
    RandomAccessFile outputFile = new RandomAccessFile("src/main/resources/data1.txt", "rw"); // 写操作的文件
    FileChannel outputChannel = outputFile.getChannel();

    // 分散读取
    ByteBuffer[] buffers = {ByteBuffer.allocate(4), ByteBuffer.allocate(1024)};
    inChannel.read(buffers);

    // 反转
    for (ByteBuffer buffer : buffers) {
      buffer.flip();
      System.out.println("当前buffer读取到的内容：" + new String(buffer.array(), 0, buffer.remaining()));
    }

    // 聚集写入
    outputChannel.write(buffers);

    inChannel.close();
    inputFile.close();
  }

  @Test
  public void testTransform() throws IOException {
    FileChannel outChannel = new FileOutputStream("src/main/resources/壁纸3.jpg").getChannel();  // 获取输出通道
    FileChannel inputChannel = new FileInputStream("src/main/resources/壁纸.jpg").getChannel();  // 获取输入通道

    //outChannel.transferFrom(inputChannel, 0, inputChannel.size());
    inputChannel.transferTo(0, inputChannel.size(), outChannel);

    // 记得关闭
    outChannel.close();
    inputChannel.close();
  }

}
